package com.maxmlr.mybatisplus.common.config;

import com.alibaba.fastjson.JSON;
import com.maxmlr.mybatisplus.common.net.util.HttpUtil;
import com.maxmlr.mybatisplus.common.resut.ResultBean;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.servlet.http.HttpServletRequest;

/**
 * 
 * @Package com.maxmlr.common.config
 * @ClassName WebLogAspect
 * @Description 日志切面
 * @author max
 * @since 2018年12月15日 下午6:12:49 
 * @version 1.0
 * @Copyright Copyright (c) 2018: www.maxmlr.com.
 */
@Aspect
@Component
public class WebLogAspect {
	Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

	@Pointcut("execution (* com.maxmlr.**.controller..*.* (..))")
//	@Pointcut("@annotation(com.maxmlr.common.inter.LogCut)")
	private void anyMethod() {
	} // 声明一个切入点，anyMethod为切入点名称

	/**
	 * @Title doAccessCheck
	 * @Description 声明该方法是一个前置通知：在目标方法开始之前执行
	 * @author max
	 * @since 2018年12月15日 下午6:13:27
	 * @param joinPoint
	 */
	//@Before("anyMethod()")
	public void doAccessCheck(JoinPoint joinPoint) {
		// 接收到请求，记录请求内容
		HttpServletRequest request = HttpUtil.getHttpServletRequest();
		Class declaringType = joinPoint.getTarget().getClass();// 类名
		Logger logger = LoggerFactory.getLogger(declaringType);// 类名

		// 记录下请求内容
		logger.info("请求URL : " + request.getRequestURL().toString());
		logger.info("请求HTTP_METHOD : " + request.getMethod());
		logger.info("请求IP : " + request.getRemoteAddr());
		logger.info("请求CLASS_METHOD : " + declaringType.getName() + "." + joinPoint.getSignature().getName());
		logger.info("请求参数ARGS : " + JSON.toJSONString(joinPoint.getArgs()));

	}

	
	/**
	 * @Title doAfterReturning
	 * @Description 后置通知
	 * @author max
	 * @since 2018年12月15日 下午6:13:41
	 * @param joinPoint
	 * @param ret
	 */
	//@AfterReturning(returning = "ret", value = "anyMethod()")
	public void doAfterReturning(JoinPoint joinPoint, Object ret) {
		Class declaringType = joinPoint.getTarget().getClass();// 类名
		Logger logger = LoggerFactory.getLogger(declaringType);// 类名
		// 处理完请求，返回内容
		logger.info("请求响应信息RESPONSE : " + JSON.toJSONString(ret));

	}

	// @After("anyMethod()")
	public void doAfter() {
		System.out.println("最终通知");
	}
	
	/**
	 * 
	 * @Title doAround
	 * @Description 环绕通知
	 * @author max
	 * @since 2018年12月15日 下午6:13:09
	 * @param pjp
	 * @return
	 * @throws Throwable
	 */
	@Around("anyMethod()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		HttpServletRequest request = HttpUtil.getHttpServletRequest();
		Class declaringType = pjp.getTarget().getClass();// 类名
		Logger logger = LoggerFactory.getLogger(declaringType);// 类名

		// 记录下请求内容
		logger.info("请求URL : " + request.getRequestURL().toString());
		logger.info("请求HTTP_METHOD : " + request.getMethod());
		logger.info("请求IP : " + request.getRemoteAddr());
		logger.info("请求CLASS_METHOD : " + declaringType.getName() + "." + pjp.getSignature().getName());
		logger.info("请求参数ARGS : " + JSON.toJSONString(pjp.getArgs()));
		StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 开始
        Object retVal = null;
		try {
			retVal = pjp.proceed();
		} catch (Exception e) {
			logger.error("请求响应发现未知异常:",e);
			retVal=new ResultBean("500","系统异常！");
		}
        stopWatch.stop();
        // 结束
        logger.info("请求响应耗时: {} ms" , stopWatch.getTotalTimeMillis());
        logger.info("请求响应信息RESPONSE : " + JSON.toJSONString(retVal));
        return retVal;
	}
	
	/**
	 * @Title doAfterThrowing
	 * @Description 发现未知异常通知
	 * @author max
	 * @since 2018年12月15日 下午6:14:29
	 * @param joinPoint
	 * @param ex
	 */
	//@AfterThrowing(value = "anyMethod()", throwing = "ex")
	public void doAfterThrowing(JoinPoint joinPoint, Exception ex) {
		Class declaringType = joinPoint.getTarget().getClass();// 类名
		Logger logger = LoggerFactory.getLogger(declaringType);// 类名
		logger.error("通知中发现未知异常:", ex);
	}
	
}